#pragma once
#ifndef __G_BOX_ORIENTED_H__
#define __G_BOX_ORIENTED_H__

#include "GPlane.h"
#include "GVector3.h"
#include "GQuaternion.h"
#include "GUtilities/GTypes.h"

namespace GMath
{
	enum GBoxPlane
	{
		G_BP_RIGHT	= 0,
		G_BP_BOTTOM	= 1,
		G_BP_LEFT	= 2,
		G_BP_TOP	= 3,
		G_BP_NEAR	= 4,
		G_BP_FAR	= 5,

		G_BP_COUNT	= 6,
	};

	enum GBoxCorner
	{
		G_BC_NEAR_BOTTOM_LEFT	= 0,
		G_BC_NEAR_BOTTOM_RIGHT	= 1,
		G_BC_NEAR_TOP_LEFT		= 2,
		G_BC_NEAR_TOP_RIGHT		= 3,
		G_BC_FAR_BOTTOM_LEFT	= 4,
		G_BC_FAR_BOTTOM_RIGHT	= 5,
		G_BC_FAR_TOP_LEFT		= 6,
		G_BC_FAR_TOP_RIGHT		= 7,

		G_BC_COUNT				= 8,
	};

	class GBoxOriented
	{
	friend class GIntersector;

	protected:
		GVector3			Right;
		GVector3			Up;
		GVector3			Front;

	public:
		GVector3			Center;
		GVector3			Dimension;

							GBoxOriented();
							GBoxOriented(const GVector3& Center, const GVector3& Dimension, const GQuaternion& Rotation);
							GBoxOriented(const GVector3& Center, const GVector3& Dimension, const GVector3& Front, const GVector3& Right, const GVector3& Up);

		void				Create(const GVector3& Center, const GVector3& Dimension, const GQuaternion& Rotation);
		void				Create(const GVector3& Center, const GVector3& Dimension, const GVector3& Front, const GVector3& Right, const GVector3& Up);

		float				Volume() const;
		float				SurfaceArea() const;

		void				GetNormal(GVector3& OutNormal, const GVector3& SurfacePoint) const;

		void				GetPlanes(OUTPUT GPlane PlaneArray[G_BP_COUNT]) const;
		void				GetCorners(OUTPUT GVector3 Arr[G_BC_COUNT]) const;
		GVector3			GetCorner(GBoxCorner Corner) const;

		const GVector3&		GetRight() const;
		const GVector3&		GetUp() const;
		const GVector3&		GetFront() const;
	
		const GBoxOriented& operator = (const GBoxOriented& Other);
	};

}

#endif